import shutil
import subprocess
import time
import logging
from .exceptions import ExternalCommandError, NetworkError

REQUIRED_COMMANDS = ['ldd', 'readelf', 'rpm2cpio', 'cpio']


def check_required_commands():
    """检查所需的外部命令是否存在"""
    missing = []
    for cmd in REQUIRED_COMMANDS:
        if not shutil.which(cmd):
            missing.append(cmd)

    if missing:
        raise ExternalCommandError(f"缺少必需的外部命令: {', '.join(missing)}.")


def run_command(command, **kwargs):
    """安全地执行外部命令"""
    try:
        return subprocess.run(command, check=True, **kwargs)
    except FileNotFoundError as exc:
        raise ExternalCommandError(f"命令未找到: {exc}") from exc
    except subprocess.CalledProcessError as exc:
        raise ExternalCommandError(f"命令执行失败: {exc}") from exc
    except OSError as exc:
        raise ExternalCommandError(f"系统错误: {exc}") from exc


def download_file_with_progress(session, url, destination):
    """通用文件下载函数，带进度显示"""
    try:
        start_time = time.monotonic()
        response = session.get(url, timeout=180, stream=True)
        response.raise_for_status()

        total_size = int(response.headers.get('content-length', 0))
        with open(destination, 'wb') as file_handle:
            for chunk in response.iter_content(chunk_size=8192):
                file_handle.write(chunk)

        duration = time.monotonic() - start_time
        if duration > 0 and total_size > 0:
            speed_kbps = (total_size / 1024) / duration
            logging.debug("Downloaded %s (%.2f KB) in %.2fs (%.2f KB/s)",
                          destination.name, total_size/1024, duration, speed_kbps)

    except Exception as exc:
        raise NetworkError(f"Failed to download {url}: {exc}") from exc
